use std::hash::{Hash, Hasher};
use std::str::FromStr;
use serde::Deserialize;
use serde_json::Value;

#[derive(serde::Serialize, serde::Deserialize,Debug,Clone,PartialEq)]
pub struct VideoData{
    pub cmd: String,
    pub method: String,
}
#[derive(serde::Serialize, serde::Deserialize,Debug,Clone,PartialEq)]
pub enum MessageType {
    Text,
    TextLogin,
    Image,
    Video(VideoData),
    File,
}

impl From<&str> for MessageType {
    fn from(value: &str) -> Self {
        if value.contains("video"){
            let video_data: VideoData = serde_json::from_str(value).unwrap();
            return MessageType::Video(video_data);
        }
        match value {
            "Text" => MessageType::Text,
            "TextLogin" => MessageType::TextLogin,
            "Image" => MessageType::Image,
            "File" => MessageType::File,
            _ => MessageType::Text,
        }
    }
}

#[derive(serde::Serialize, serde::Deserialize,Debug,Clone)]
pub struct Message {
    pub sender_account: String,
    pub to_account: String,
    pub message_type:MessageType,
    pub content: Vec<u8>,
}
pub fn serde_bytes<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error> where D: serde::Deserializer<'de> {
    let value: Value = Deserialize::deserialize(deserializer)?;
    log::info!("value: {:#?}", value);
    // 对 value 进行特殊处理，例如转换为字符串或进行计算等
    log::info!("value: {:#?}", value.to_string());
    let special_value =  value.to_string().into_bytes();
    Ok(special_value)
}
impl Message {
    pub fn new(sender_account: String, to_account: String, message_type:MessageType, content: Vec<u8>) -> Self {
        Self {
            sender_account,
            to_account,
            message_type,
            content,
        }
    }
}


impl PartialEq<Self> for Message {
    fn eq(&self, other: &Self) -> bool {
        self.sender_account == other.sender_account
            && self.to_account == other.to_account
            && self.content == other.content
    }
}

impl Eq for Message {
    
}
impl Hash for Message {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.sender_account.hash(state);
        self.to_account.hash(state);
        self.content.hash(state);
    }
}
#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_message() {
        let messageType:MessageType = "Image".to_string().as_str().into();
        assert_eq!(messageType, MessageType::Image);
    }
}